Package org.python.pydev.editor.codecompletion.templates

Source Code of org.python.pydev.editor.codecompletion.templates.DocumentTemplateContextWithIndent

/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.editor.codecompletion.templates;

import java.util.List;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.templates.DocumentTemplateContext;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateBuffer;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.jface.text.templates.TemplateException;
import org.eclipse.jface.text.templates.TemplateTranslator;
import org.python.pydev.core.IIndentPrefs;
import org.python.pydev.core.docutils.PySelection;
import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.core.log.Log;

import com.aptana.shared_core.string.FastStringBuffer;

public class DocumentTemplateContextWithIndent extends DocumentTemplateContext {

    private final String indentTo;
    private IIndentPrefs indentPrefs;

    /**
     * Note that it's in the default context because it should be used on subclasses.
     */
    /* default */DocumentTemplateContextWithIndent(TemplateContextType type, IDocument document, int offset,
            int length, String indentTo, IIndentPrefs indentPrefs) {
        super(type, document, offset, length);
        this.indentTo = indentTo;
        this.indentPrefs = indentPrefs;
    }

    @Override
    public TemplateBuffer evaluate(Template template) throws BadLocationException, TemplateException {

        if (!canEvaluate(template)) {
            return null;
        }

        String spacesIndentString = StringUtils.createSpaceString(indentPrefs.getTabWidth());

        //indent to needed level and
        //replace any \t for the indentation string
        String pattern = template.getPattern();
        List<String> splitted = StringUtils.splitInLines(pattern);

        boolean changed = false;
        if (indentPrefs.getUseSpaces(true)) {
            if (pattern.indexOf("\t") != -1) {
                template = createNewTemplate(template, StringUtils.replaceAll(pattern, "\t", spacesIndentString));
                changed = true;
            }
        } else {
            if (pattern.indexOf(spacesIndentString) != -1) {
                FastStringBuffer newPattern = new FastStringBuffer();
                FastStringBuffer newTabsIndent = new FastStringBuffer();

                for (int i = 0; i < splitted.size(); i++) {
                    String string = splitted.get(i);

                    int spacesFound = 0;
                    while (string.length() > 0 && string.charAt(0) == ' ') {
                        string = string.substring(1);
                        spacesFound += 1;
                    }

                    int tabsToAdd = 0;
                    if (spacesFound > 0) {
                        tabsToAdd = spacesFound / spacesIndentString.length();
                        if (spacesFound % spacesIndentString.length() != 0) {
                            tabsToAdd += 1;
                        }
                        newTabsIndent.clear();
                        for (int j = 0; j < tabsToAdd; j++) {
                            newTabsIndent.append("\t");
                        }
                        newPattern.append(newTabsIndent);
                    }
                    newPattern.append(string);
                }
                template = createNewTemplate(template, newPattern.toString());
                changed = true;
            }
        }

        //recreate it (if needed).
        if (changed) {
            pattern = template.getPattern();
            splitted = StringUtils.splitInLines(pattern);
        }

        String indentToStr = indentTo != null ? indentTo : "";
        String endLineDelim = PySelection.getDelimiter(this.getDocument());

        int size = splitted.size();
        if (size > 0) {

            FastStringBuffer buffer = new FastStringBuffer("", (pattern.length() + (size * 2))
                    + ((size + 1) * indentToStr.length()));
            for (int i = 0; i < size; i++) { //we don't want to get the first line

                if (i != 0) {
                    //the 1st line is not indented (that's where the user requested the completion -- others should be indented to it)
                    buffer.append(indentToStr);
                }

                String str = splitted.get(i);

                //we have to make the new line delimiter correct:
                //https://sourceforge.net/tracker/index.php?func=detail&aid=2019419&group_id=85796&atid=577329
                boolean hasNewLine = false;
                if (str.endsWith("\r") || str.endsWith("\n")) {
                    hasNewLine = true;
                    if (str.endsWith("\r\n")) {
                        str = str.substring(0, str.length() - 2);
                    } else {
                        str = str.substring(0, str.length() - 1);
                    }
                }
                buffer.append(str);
                if (hasNewLine) {
                    buffer.append(endLineDelim);
                }
            }
            //just to change the pattern...
            template = createNewTemplate(template, buffer.toString());
        }

        try {
            TemplateTranslator translator = new TemplateTranslator();
            TemplateBuffer templateBuffer = translator.translate(template);

            getContextType().resolve(templateBuffer, this);

            return templateBuffer;
        } catch (Exception e) {
            Log.log(e);
            throw new RuntimeException(e);
        }
    }

    private Template createNewTemplate(Template template, String newString) {
        return new Template(template.getName(), template.getDescription(), template.getContextTypeId(), newString,
                template.isAutoInsertable());
    }

}
TOP

Related Classes of org.python.pydev.editor.codecompletion.templates.DocumentTemplateContextWithIndent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.